package com.itheima.health.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.health.common.RedisConst;
import com.itheima.health.dao.CheckGroupDao;
import com.itheima.health.dao.CheckGroupItemDao;
import com.itheima.health.dao.CheckItemDao;
import com.itheima.health.entity.PageResult;
import com.itheima.health.entity.QueryPageBean;
import com.itheima.health.exception.CustomizeException;
import com.itheima.health.pojo.CheckGroup;
import com.itheima.health.pojo.CheckGroupItem;
import com.itheima.health.pojo.CheckItem;
import com.itheima.health.service.CheckGroupService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
@DubboService
public class CheckGroupServiceImpl implements CheckGroupService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CheckGroupDao checkGroupDao;

    @Autowired
    private CheckGroupItemDao checkGroupItemDao;

    @Autowired
    private CheckItemDao checkItemDao;

    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        /*
        * @Date: 4:53 下午 2021/1/6
        * @param: [queryPageBean]
        * @return: com.itheima.health.entity.PageResult
        * @Description: 使用selectByExample进行sql查询
        * 1、先创建Example对象
        * 2、调用createCriteria获取criteria
        * 3、criteria调用其sql方法
        */
        PageResult pageResult = null;
        if (!redisTemplate.hasKey(RedisConst.FIND_CHECKGROUP_PAGE)){
            PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
            Example example = new Example(CheckGroup.class);
            Example.Criteria criteria = example.createCriteria();
            String queryString = queryPageBean.getQueryString();
            //使用StringUtils进行判断是否为空
            if (!StringUtils.isEmpty(queryString)){
                //criteria有其他SQl方法
                criteria.orLike("name","%"+queryString+"%");
                criteria.orLike("code","%"+queryString+"%");
                criteria.orLike("helpCode","%"+queryString+"%");
            }
            Page<CheckGroup> page = (Page<CheckGroup>) checkGroupDao.selectByExample(example);
            pageResult = new PageResult(page.getTotal(), page.getResult());
            redisTemplate.boundValueOps(RedisConst.FIND_CHECKGROUP_PAGE).set(pageResult);
        }else {
            pageResult = (PageResult) redisTemplate.boundValueOps(RedisConst.FIND_CHECKGROUP_PAGE).get();
        }
        return pageResult;
    }

    @Override
    @Transactional
    public boolean add(CheckGroup checkGroup, Integer[] ids) {
        boolean flag = false;
        int count = checkGroupDao.insertSelective(checkGroup);
        Integer key = checkGroup.getId();
        log.info("[预约-检查组-主键回显] - key - {}", key);
        log.info("[预约-检查组-检查项id] - id - {}", Arrays.toString(ids));
        if (count > 0 && ids.length > 0) {
            for (Integer id : ids) {
                checkGroupItemDao.add(key, id);
            }

            flag = true;
        }
        return flag;
    }

    @Override
    @Transactional
    public boolean delete(Integer id) {
        /*
        * @Date: 12:29 下午 2021/1/6
        * @param: [id]
        * @return: boolean
        * @Description: 未完成待续。。。
        */
        boolean flag = false;
        CheckGroupItem checkGroupItem = new CheckGroupItem();
        checkGroupItem.setCheckgroupId(id);
        int selectCount = checkGroupItemDao.selectCount(checkGroupItem);
        log.info("[预约-检查组-根据id检查项与检查组关联数据] - checkGroupItem - {}", checkGroupItem);
        if (selectCount > 0) {
            throw new CustomizeException("该检查组有关联的检查项，不可以删除");
        }
        int count = checkGroupDao.deleteByPrimaryKey(id);
        if (count > 0) {
            flag = true;
        }

        return flag;
    }

    @Override
    public CheckGroup findById(Integer id) {
        /*
        * @Date: 4:59 下午 2021/1/6
        * @param: [id]
        * @return: com.itheima.health.pojo.CheckGroup
        * @Description: 根据id返回CheckGroup
        * 注意：由于前端发送三次请求，改变获取数据方式
        * 本方法返回的checkItems数据前端不进行使用，直接忽略即可
        */
        //根句id查询CheckGroup数据
        CheckGroup checkGroup = checkGroupDao.selectByPrimaryKey(id);
        //根据id查询CheckGroup和CheckItem中间表，得出检查项id
        CheckGroupItem checkGroupItem = new CheckGroupItem();
        checkGroupItem.setCheckgroupId(id);
        List<CheckGroupItem> checkGroupItemList = checkGroupItemDao.select(checkGroupItem);
        //new一个ArrayList容器用于存放CheckItem
        ArrayList<CheckItem> checkItems = new ArrayList<>();
        //循环遍历检查项id
        for (CheckGroupItem groupItem : checkGroupItemList) {
            //取出CheckItem的id
            Integer checkitemId = groupItem.getCheckitemId();
            //根据CheckItem的id查询CheckItem数据
            CheckItem checkItem = checkItemDao.selectByPrimaryKey(checkitemId);
            //将CheckItem存入ArrayList容器中
            checkItems.add(checkItem);
        }
        //将ArrayList容器内数据存入CheckGroup中
        checkGroup.setCheckItems(checkItems);
        log.info("[预约-检查组-findById-ArrayList中的数据]- checkItems - {}", checkItems);
        return checkGroup;
    }

    @Override
    public List<Integer> findByCheckGroupIdAndCheckItemId(Integer id) {
        /*
         * @Date: 2:51 下午 2021/1/5
         * @param: [id]
         * @return: java.util.List<java.lang.Integer>
         * @Description: 根据CheckGroupId查询CheckGroup和CheckItem中间表
         * 求出CheckItemId，循环遍历存入ArrayList集合
         */
        CheckGroupItem checkGroupItem = new CheckGroupItem();
        checkGroupItem.setCheckgroupId(id);
        List<CheckGroupItem> checkGroupItemList = checkGroupItemDao.select(checkGroupItem);
        ArrayList<Integer> integerArrayList = new ArrayList<>();
        //遍历存入CheckItemId
        for (CheckGroupItem groupItem : checkGroupItemList) {
            integerArrayList.add(groupItem.getCheckitemId());
        }

        return integerArrayList;
    }

    @Override
    @Transactional
    public boolean update(CheckGroup checkGroup, Integer[] ids) {
        /*
         * @Date: 4:20 下午 2021/1/5
         * @param: [checkGroup, ids]
         * @return: boolean
         * @Description: 根据CheckGroupID先清除原有关联的CheckItem信息，然后添加新的CheckItem信息
         * 为了防止出现异常导致只进行删除，并没有进行新增，应该使用事务
         */
        boolean flag = false;
        //修改检查组信息
        int updateCount = checkGroupDao.updateByPrimaryKeySelective(checkGroup);
        Integer checkGroupId = checkGroup.getId();
        //根据CheckGroupId删除原有关联CheckItemId信息
        checkGroupItemDao.deleteById(checkGroupId);
        if (ids.length > 0) {
            for (Integer id : ids) {
                //根据CheckGroupId添加新的CheckItemId信息
                checkGroupItemDao.add(checkGroupId, id);
            }
            flag = true;
        }
        if (updateCount > 0) {
            flag = true;
        }
        return flag;
    }

    @Override
    public List<CheckGroup> findAll() {
        List<CheckGroup> checkGroupList = null;
        if (!redisTemplate.hasKey(RedisConst.FIND_CHECKGROUP_ALL)){
            checkGroupList = checkGroupDao.selectAll();
            redisTemplate.boundValueOps(RedisConst.FIND_CHECKGROUP_ALL).set(checkGroupList);
        }else {
            checkGroupList = (List<CheckGroup>) redisTemplate.boundValueOps(RedisConst.FIND_CHECKGROUP_ALL).get();
        }
        return checkGroupList;
    }


}
